<template lang="pug">
  .design-area-form.w-100.h-100
    i.design-tree-icon(class="el-icon-menu" v-if="quickCreatePage" @click="treeShow=!treeShow")
    .design-tree-box
      .design-tree(v-if="quickCreatePage" :class="{'design-tree-hidden':!treeShow, 'design-tree-show': treeShow}")
        el-tree(:data="treeData" :default-expand-all="true" :render-content="treeRenderContent" style="width:1000px;")
      el-form(@submit.native.prevent :class="designDeviceChoose==='APP'?'APP-design':'PC-design'" :model="properties" :ref="formRef"  :label-width="formRef.indexOf('designTab')>-1&&globalStyle.labelWidth?globalStyle.labelWidth:'80px'")
        draggable.design-area-drag(@add="dragAdd" v-model="formInfo.list" :options="dragOptions2" :style="formRef.indexOf('designTab')>-1?globalStyle.globalStyle:''")
          puligin-defs-item.plugin-defs-item(v-if="item" v-for="item in formInfo.list" :key="item.config.componentId"  :editor="'true'" :pluginDefsInfo="item" :siblings="formInfo.list")
    el-dialog(title="存为共享组件" :visible.sync="shareDialogVisible" @close="shareDialogClose" :append-to-body='true')
      el-form(ref="shareForm" :model="shareForm" label-width="120px")
        el-form-item.mt-3(label="共享组件名称" prop="name" :rules="[{ required: true, message: '请输入共享组件名称', trigger: ['blur','change']}]")
          el-input(v-model="shareForm.name")
        el-row.mt-3.pb-3.text-center
          el-button(@click="shareDialogVisible=false") 取 消
          el-button(type="primary" @click="saveAsSharePlugin") 保 存
    .bottom-status.clearfix
      .bottom-status-one(v-for="item in parentComponent" :class="{'select-active':!selectPluginDefsInfo&&item.name==='全局'}" @click="BottomSelect(item)" @mouseout="optionMouseOut" @mouseenter="optionMouseEnter(item)")
        | {{item.name}}
        .sjx-box
          .sjx-out
            .sjx-in
      .bottom-status-one.select-active(v-if="selectPluginDefsInfo")
        | {{selectPluginDefsInfo.name}}
        .sjx-box
          .sjx-out
            .sjx-in
      el-select(v-if="childComponent.length>0" v-model="selectOptionModel" value-key="componentId" @change="selectChange" size="mini")
        el-option(v-for="item in childComponent" :label="item.name" :value="item" :key="item.config.componentId" @mouseout.native="optionMouseOut" @mouseenter.native="optionMouseEnter(item)")

</template>
<script>
import draggable from 'vuedraggable'
import puliginDefsItem from '../formPlugins/puliginDefsItem/puliginDefsItem'
import _ from 'lodash'
import {
  deleteFunctionKey,
  addFunctionKey,
  addId,
  pluginDefsConfigValidate,
  addSpecialFlag
} from '../formPlugins/utils/drag.js'
import DataInterfaceObserverManage from '../formPlugins/dataInterface/observerManage'
import * as api from '../formPlugins/service'
import { addCSSWithId, addPrefixToCssText, removeElementBySelector } from '../../../../common/utils/domUtil'
import svgIcon from '../../../../common/plugins/svgIcon/svgIcon'
export default {
  components: { draggable, puliginDefsItem },
  props: ['designDeviceChoose', 'formInfo', 'properties', 'formRef', 'sortable', 'globalStyle', 'customStyle', 'labelWidth', 'treeDragList', 'quickCreatePage'],
  data() {
    return {
      pluginDefsInfo: undefined, // 组件hover传来的参数
      dataInterfaceObserverManage: new DataInterfaceObserverManage(),
      // 共享组件
      shareDialogVisible: false,
      shareForm: {
        name: ''
      },
      parentComponent: [],
      childComponent: [],
      selectPluginDefsInfo: undefined,
      selectOptionModel: undefined,
      treeShow: false,
      treeData: [],
      globStyleId: _.uniqueId('globStyleId')
    }
  },
  inject: ['operaTemplateRoot'],
  provide() {
    return {
      rootForm: this,
      components: {} // 用于ref
    }
  },
  watch: {
    'operaTemplateRoot.chooseComponentId': function (chooseComponentId) {
      this.parentComponent = []
      this.childComponent = this.formInfo.list
      this.findParentPlugin(chooseComponentId)
      this.parentComponent.unshift({ name: '全局' })
      if (chooseComponentId) {
        this.childComponent = []
        _.forEach(this.formInfo.list, option => {
          this.findChildPlugin(undefined, option, chooseComponentId)
        })
      } else {
        this.operaTemplateRoot.optionHoverId = ''
        this.selectPluginDefsInfo = undefined
      }
    },
    'customStyle': function () {
      removeElementBySelector('#' + this.globStyleId)
      if (this.customStyle) {
        addCSSWithId(addPrefixToCssText(this.customStyle, '.' + this.globStyleId), this.globStyleId)
      }
    }
  },
  methods: {
    // 树形拖拽数据处理
    dragListAddChildren(option) {
      if (option.category === 'layout' && option.config.containers.length > 0) {
        option.children = _.flattenDeep(_.map(option.config.containers, 'children'))
        _.forEach(option.config.containers, one => {
          if (one.children && one.children.length > 0) {
            _.forEach(one.children, child => {
              // option.children.push(child)
              this.dragListAddChildren(child)
            })
          }
        })
      }
    },
    // 删除children字段
    dragListDeleteChildren(option) {
      delete option.children
      if (option.category === 'layout' && option.config.containers.length > 0) {
        _.forEach(option.config.containers, one => {
          if (one.children && one.children.length > 0) {
            _.forEach(one.children, child => {
              this.dragListDeleteChildren(child)
            })
          }
        })
      }
      return _.cloneDeep(option)
    },
    cloneData(value) {
      let valueClone = _.cloneDeep(value)
      if (!('config' in valueClone)) {
        valueClone.config = valueClone.initConfigDataFn()
      }
      if ('children' in valueClone) {
        this.dragListDeleteChildren(valueClone)
      }
      // addId(valueClone)
      return _.cloneDeep(valueClone)
    },
    treeRenderContent(h, self) {
      let data = [self.data]
      return h(
        draggable,
        { tag: 'component', props: { clone: this.cloneData, value: data, options: this.dragOptions1 } },
        [
          h('div', [h(svgIcon, { style: { marginRight: '4px' }, props: { 'icon-class': '组件' + data[0].label } }), h('span', data[0].config.name || data[0].label)])
        ]
      )
    },
    dragListToTree() {
      this.treeData = _.cloneDeep(this.treeDragList)
      _.forEach(this.treeData, one => {
        addSpecialFlag(one, 'device', this.designDeviceChoose)
        addFunctionKey(one)
        this.dragListAddChildren(one)
      })
    },
    // 拖拽使底部栏重新渲染
    dragAdd(v) {
      this.operaTemplateRoot.chooseComponentId = ''
      this.$nextTick(() => {
        this.BottomSelect((v.item && v.item._underlying_vm_) ? v.item._underlying_vm_ : v)
      })
    },
    findParentPlugin(id) {
      if (id) {
        _.forEach(this.formInfo.list, option => {
          this.findParent(undefined, option, id)
        })
      }
    },
    findParent(parent, option, id) {
      if (option.config.componentId === id) {
        if (parent) {
          this.parentComponent.unshift(parent)
          this.findParentPlugin(parent.config.componentId)
        }
      } else if (option.category === 'layout' && option.config.containers.length > 0) {
        _.forEach(option.config.containers, one => {
          if (one.children && one.children.length > 0) {
            _.forEach(one.children, child => {
              this.findParent(option, child, id)
            })
          }
        })
      } else {
        return false
      }
    },
    findChildPlugin(parent, option, id) {
      if (option.config.componentId === id) {
        this.findChild(option)
      } else if (option.category === 'layout' && option.config.containers.length > 0) {
        _.forEach(option.config.containers, one => {
          if (one.children && one.children.length > 0) {
            _.forEach(one.children, child => {
              this.findChildPlugin(option, child, id)
            })
          }
        })
      } else {
        return false
      }
    },
    findChild(option) {
      if (option.category === 'layout' && option.config.containers.length > 0) {
        _.forEach(option.config.containers, one => {
          if (one.children && one.children.length > 0) {
            _.forEach(one.children, child => {
              this.childComponent.push(child)
            })
          }
        })
      } else {

      }
    },
    findOnePluginByComponentId(option, componentId) {
      if (option.config.componentId === componentId) {
        this.findOnePlugin = option
      } else if (option.category === 'layout' && option.config.containers.length > 0) {
        _.forEach(option.config.containers, one => {
          if (one.children && one.children.length > 0) {
            _.forEach(one.children, child => {
              this.findOnePluginByComponentId(child, componentId)
            })
          }
        })
      }
    },
    // 删除
    deletePluginDefs(value) {
      this.pluginDefsInfo = value
      if (this.operaTemplateRoot.chooseComponentId && this.operaTemplateRoot.chooseComponentId !== this.pluginDefsInfo.config.componentId) {
        _.forEach(this.formInfo.list, one => {
          this.findOnePluginByComponentId(one, this.operaTemplateRoot.chooseComponentId)
          if (this.findOnePlugin) {
            // this.dragAdd(this.findOnePlugin)
            this.operaTemplateRoot.chooseComponentId = ''
            this.$nextTick(() => {
              this.BottomSelect(this.findOnePlugin)
            })
          }
        })
      }
      this.operaTemplateRoot.deletePluginDefs(this.pluginDefsInfo)
      // this.$emit('deletePluginDefs', this.pluginDefsInfo)
    },
    // 共享
    sharePluginDefs(value) {
      this.pluginDefsInfo = value
      this.shareDialogVisible = true
    },
    saveAsSharePlugin() {
      this.$refs.shareForm.validate((valid) => {
        if (valid) {
          // 判断保存共享的组件以及内部子组件配置是否正确
          let pluginDefsInfoClone = _.cloneDeep(this.pluginDefsInfo)
          let saveShareComponent = () => {
            api.createShareComponent(this.shareForm).then(_ => {
              this.$message.success('组件共享成功!')
              this.operaTemplateRoot.saveAsSharePlugin()
              // this.$emit('saveAsSharePlugin')
            }).catch(_ => {
              this.$message.error('组件共享失败!')
            }).finally(_ => {
              this.shareDialogVisible = false
            })
          }
          pluginDefsConfigValidate(this.pluginDefsInfo).then(data => {
            this.shareForm.component = JSON.stringify(deleteFunctionKey(pluginDefsInfoClone))
            api.getShareComponentList('', '', { name: '' }).then(data => {
              let sharePluginDefs = data.rows
              let find = _.find(sharePluginDefs, one => { return one.name === this.shareForm.name })
              if (find) {
                this.$confirm('该名称的共享组件已存在，继续操作将覆盖原有共享组件，是否继续?', '提示', {
                  confirmButtonText: '确定',
                  cancelButtonText: '取消',
                  type: 'warning',
                  center: true
                }).then(() => {
                  saveShareComponent()
                }).catch(() => {
                  this.$message.info('组件共享取消!')
                })
              } else {
                saveShareComponent()
              }
            })
          }).catch(errData => {
            let pluginDefsInfoError = errData.plugin
            // this.operaTemplateRoot.chooseComponentId = pluginDefsInfoError.config.componentId
            this.operaTemplateRoot.$refs.configArea.compontentInfo = undefined
            this.operaTemplateRoot.$refs.configArea.compontentConfig(pluginDefsInfoError)
            this.$message.error('组件共享失败 , 目前选中的组件配置有误!')
            this.shareDialogVisible = false
          })
        }
      })
    },
    // 底部状态栏
    globalClick() {
      this.selectOptionModel = undefined
      this.selectPluginDefsInfo = undefined
      this.operaTemplateRoot.optionHoverId = ''
      this.operaTemplateRoot.configArea().showGlobalConfig()
      // 底部刷新
      this.parentComponent = [{ name: '全局' }]
      this.childComponent = this.formInfo.list
    },
    optionMouseOut() {
      this.operaTemplateRoot.optionHoverId = ''
    },
    optionMouseEnter(item) {
      if (item.name !== '全局') {
        this.operaTemplateRoot.optionHoverId = item.config.componentId
      }
    },
    selectChange(v) {
      this.BottomSelect(v)
    },
    BottomSelect(v) {
      if (v.name === '全局') {
        this.globalClick()
      } else {
        this.selectOptionModel = undefined
        this.pluginDefsInfo = v
        this.selectPluginDefsInfo = this.pluginDefsInfo
        this.operaTemplateRoot.selectPluginDefs(this.pluginDefsInfo)
        // this.$emit('selectPluginDefs', this.pluginDefsInfo)
      }
    },
    // 选中组件
    editPluginDefs(value) {
      this.pluginDefsInfo = value
      this.selectPluginDefsInfo = this.pluginDefsInfo
      this.operaTemplateRoot.selectPluginDefs(this.pluginDefsInfo)
      // this.$emit('selectPluginDefs', this.pluginDefsInfo)
    },
    shareDialogClose() {
      this.$refs.shareForm.resetFields()
    }
  },
  mounted() {
    if (this.formRef.indexOf('designTab') > -1) {
      this.$el.querySelectorAll('.design-area-drag')[0].classList.add(this.globStyleId)
    }
  },
  beforeDestroy() {
    // 清除自定义样式
    removeElementBySelector('#' + this.globStyleId)
  },
  created() {
    // 全局自定义样式
    if (this.customStyle) {
      addCSSWithId(addPrefixToCssText(this.customStyle, '.' + this.globStyleId), this.globStyleId)
    }
    // 左边组件拖拽
    this.dragOptions1 = {
      animation: 0,
      ghostClass: 'ghosta',
      // 分组
      group: {
        name: 'templateComponts',
        pull: 'clone',
        revertClone: false,
        put: false
      },
      // 禁止拖动排序
      sort: false
    }
    // 右边拖拽
    this.dragOptions2 = {
      animation: 0,
      ghostClass: 'ghost',
      scroll: true,
      group: {
        // put: true
        name: 'templateComponts',
        put: ['templateComponts']
      }
    }
    _.forEach(this.formInfo.list, one => {
      addFunctionKey(one)
      // addId(one)
    })
    this.dragListToTree()
    this.parentComponent = [{ name: '全局' }]
    this.childComponent = this.formInfo.list
  }
}
</script>
<style lang="scss" scoped>
  .design-area-form {
    width: 100%;
    height: 100%;
    position: relative;
    overflow: auto;
    box-sizing: border-box;
    .design-tree-icon {
      position: absolute;
      top: 0;
      left: 15px;
      font-size: 25px;
    }
    .design-tree-box {
      display: flex;
      height: calc(100% - 46px);
      width: 100%;
      overflow: auto;
      .design-tree {
        outline: 1px solid #ccc;
        height: calc(100% - 30px);
        margin-top: 30px;
        width: 200px;
        min-width: 200px;
        margin-right:10px;
        overflow: auto;
        box-sizing: border-box;
        font-size:14px;
      }
      .design-tree-hidden {
        height: 0;
        width: 0;
        min-width: 0px;
        transition: 0.5s ease;
      }
      .design-tree-show {
        height: calc(100% - 30px);
        width: 200px;
        min-width: 200px;
        transition: 0.5s ease;
      }
    }
    .design-area-drag {
      // width: 100%;
      height: 100%;
      border: 1px solid transparent;
      box-sizing: border-box;
    }
    .puligin-defs-icon {
      width: 90px;
      height: 24px;
      line-height: 24px;
      text-align: right;
      .icon {
        cursor: pointer;
        margin-left: 10px;
      }
    }
    .APP-design {
      // flex:1;
      background: url(../assets/phone.png) no-repeat;
      background-size: 100% 100%;
      width: 322px;
      min-width: 322px;
      height: 600px;
      margin: auto;
      padding: 108px 17px 100px 20px;
      box-sizing: unset;
      .design-area-drag {
        overflow: auto;
      }
    }
    .PC-design {
      flex: 1;
      height: 100%;
      // height:calc(100% - 46px);
      // overflow: auto;
      // width: 100%;
      width:calc(100% - 210px);
      box-sizing: border-box;
      .design-area-drag {
        padding: 15px;
        overflow: auto;
      }
    }
    .bottom-status {
      border-top:1px solid #ccc;
      white-space: nowrap;
      padding-top: 10px;
      overflow-x: auto;
      .bottom-status-one {
        display: inline-block;
        padding-left: 24px;
        margin-left: -18px;
        line-height: 26px;
        background: #eee;
        cursor: pointer;
        &:hover {
          background: #ccc;
          .sjx-in {
            border-left: 17px solid #ccc !important;
          }
        }
        .sjx-box {
          float: right;
          .sjx-out {
            width: 0;
            height: 0;
            border-top: 13px solid transparent;
            border-bottom: 13px solid transparent;
            border-left: 18px solid #aaa;
            z-index: 9;
            position: relative;
            .sjx-in {
              width: 0;
              height: 0;
              border-top: 12px solid transparent;
              border-bottom: 12px solid transparent;
              border-left: 17px solid #eee;
              float: right;
              z-index: 9;
              position: absolute;
              top: -12px;
              left: -18px;
            }
          }
        }
      }
      .select-active {
        background: #ccc;
        .sjx-box {
          background: #fff;
          .sjx-in {
            border-left: 17px solid #ccc !important;
          }
        }

      }
    }
  }
</style>
